package com.imddysc.springbootbatch001.utils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JacksonJsonUtils {

	private final static ObjectMapper objectMapper = new ObjectMapper();

	static {
		objectMapper
				// 设置允许序列化空的实体类（否则会抛出异常）
				.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
				// 设置 把java.util.Date, Calendar输出为数字（时间戳）
				.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
				// 设置在遇到未知属性的时候不抛出异常
				.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
				// 强制JSON 空字符串("")转换为null对象值
				.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)
				// 设置数字丢失精度问题
				.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
				// 设置没有引号的字段名
				.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
				// 设置允许单引号
				.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES)
				// 设置DateFormat格式化格式
				.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
				// 设置接受只有一个元素的数组的反序列化
				.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
	}

	public JacksonJsonUtils() {
	}

	public static ObjectMapper getInstance() {
		return objectMapper;
	}

	/** javaBean,list,array convert to json string */
	public static String obj2json(Object obj) throws Exception {
		return objectMapper.writeValueAsString(obj);
	}

	/** json string convert to javaBean */
	public static <T> T json2pojo(String jsonStr, Class<T> clazz) throws Exception {
		return objectMapper.readValue(jsonStr, clazz);
	}

	/** json string convert to map */
	public static <T> Map<String, Object> json2map(String jsonStr) throws Exception {
		return objectMapper.readValue(jsonStr, Map.class);
	}

	/** json string convert to map with javaBean */
	public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz) throws Exception {
		Map<String, Map<String, Object>> map = (Map<String, Map<String, Object>>) objectMapper.readValue(jsonStr,
				new TypeReference<Map<String, T>>() {
				});
		Map<String, T> result = new HashMap<String, T>();
		for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
			result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
		}
		return result;
	}

	/** json array string convert to list with javaBean */
	public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
		List<Map<String, Object>> list = (List<Map<String, Object>>) objectMapper.readValue(jsonArrayStr,
				new TypeReference<List<T>>() {
				});
		List<T> result = new ArrayList<T>();
		for (Map<String, Object> map : list) {
			result.add(map2pojo(map, clazz));
		}
		return result;
	}

	/** map convert to javaBean */
	public static <T> T map2pojo(Map map, Class<T> clazz) {
		return objectMapper.convertValue(map, clazz);
	}

}
